﻿using System;
using System.Net;
using SomeKit.Http;
using SomeKit.Serialization;

namespace SomeKit.TypeSafe.BasicAuthentication
{
    public static partial class ClientHelper
    {
        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>.
        /// </summary>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void Put(this Uri uri, string userName, string password,
            Action<Exception> errorHandler,
            Action<HttpWebRequest> headerHandler = null)
        {
            uri.Put(errorHandler, headerHandler.AppendBasicAuthentication(userName, password));
        }

        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>.
        /// </summary>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="handler">The final handler.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void Put(this Uri uri, string userName, string password,
            Action handler,
            Action<Exception> errorHandler,
            Action<HttpWebRequest> headerHandler = null)
        {
            uri.Put(handler, errorHandler, headerHandler.AppendBasicAuthentication(userName, password));
        }

        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>.
        /// </summary>
        /// <typeparam name="BODY">A type of object to be sent to the server.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="body">The body part of the request.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="serializer">A method that is capable of serializing <paramref name="body"/>.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void Put<BODY>(this Uri uri, string userName, string password,
            BODY body, Action<Exception> errorHandler, Func<BODY, string> serializer,
            Action<HttpWebRequest> headerHandler = null)
        {
            uri.Put<BODY>(body, errorHandler, serializer, headerHandler.AppendBasicAuthentication(userName, password));
        }
        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>. The request body is expected to be formatted in XML.
        /// </summary>
        /// <typeparam name="BODY">A type of object to be sent to the server.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="body">The body part of the request.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void PutXml<BODY>(this Uri uri, string userName, string password,
            BODY body, Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            uri.PutXml(body, errorHandler, headerHandler.AppendXmlAndBasicAuthentication(userName, password));
        }
        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>. The request body is expected to be formatted in JSON.
        /// </summary>
        /// <typeparam name="BODY">A type of object to be sent to the server.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="body">The body part of the request.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void PutJson<BODY>(this Uri uri, string userName, string password,
            BODY body, Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            uri.PutJson(body, errorHandler, headerHandler.AppendJsonAndBasicAuthentication(userName, password));
        }

        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>.
        /// </summary>
        /// <typeparam name="BODY">A type of object to be sent to the server.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="body">The body part of the request.</param>
        /// <param name="handler">The final handler.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="serializer">A method that is capable of serializing <paramref name="body"/>.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void Put<BODY>(this Uri uri, string userName, string password,
            BODY body, Action handler, Action<Exception> errorHandler, Func<BODY, string> serializer,
            Action<HttpWebRequest> headerHandler = null)
        {
            uri.Put<BODY>(body, handler, errorHandler, serializer, headerHandler.AppendBasicAuthentication(userName, password));
        }

        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>. The request body is expected to be formatted in XML.
        /// </summary>
        /// <typeparam name="BODY">A type of object to be sent to the server.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="body">The body part of the request.</param>
        /// <param name="handler">The final handler.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void PutXml<BODY>(this Uri uri, string userName, string password,
            BODY body, Action handler, Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            uri.PutXml(body, handler, errorHandler, headerHandler.AppendXmlAndBasicAuthentication(userName, password));
        }
        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>. The request body is expected to be formatted in JSON.
        /// </summary>
        /// <typeparam name="BODY">A type of object to be sent to the server.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="body">The body part of the request.</param>
        /// <param name="handler">The final handler.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void PutJson<BODY>(this Uri uri, string userName, string password,
            BODY body, Action handler, Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            uri.PutJson(body, handler, errorHandler, headerHandler.AppendJsonAndBasicAuthentication(userName, password));
        }

        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>.
        /// </summary>
        /// <typeparam name="RESULT">The type of the result parameter.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="handler">The handler receiving the resultant object.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="deserializer">A method capable of deserializing the resultant object.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void Put<RESULT>(this Uri uri, string userName, string password, Action<RESULT> handler,
            Action<Exception> errorHandler, Func<string, RESULT> deserializer, Action<HttpWebRequest> headerHandler = null)
        {
            uri.Put(handler, errorHandler, deserializer, headerHandler.AppendBasicAuthentication(userName, password));
        }
        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>. The request body is expected to be formatted in XML.
        /// </summary>
        /// <typeparam name="RESULT">The type of the result parameter.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="handler">The handler receiving the resultant object.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void PutXml<RESULT>(this Uri uri, string userName, string password, Action<RESULT> handler,
            Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            uri.PutXml(handler, errorHandler, headerHandler.AppendXmlAndBasicAuthentication(userName, password));
        }
        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>. The request body is expected to be formatted in JSON.
        /// </summary>
        /// <typeparam name="RESULT">The type of the result parameter.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="handler">The handler receiving the resultant object.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void PutJson<RESULT>(this Uri uri, string userName, string password, Action<RESULT> handler,
            Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            uri.PutJson(handler, errorHandler, headerHandler.AppendJsonAndBasicAuthentication(userName, password));
        }

        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>.
        /// </summary>
        /// <typeparam name="BODY">A type of object to be sent to the server.</typeparam>
        /// <typeparam name="RESULT">The type of the result parameter.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="body">The body part of the request.</param>
        /// <param name="handler">The handler receiving the resultant object.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="serializer">A method that is capable of serializing <paramref name="body"/>.</param>
        /// <param name="deserializer">A method capable of deserializing the resultant object.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void Put<BODY, RESULT>(this Uri uri, string userName, string password, BODY body,
            Action<RESULT> handler, Action<Exception> errorHandler, Func<BODY, string> serializer, Func<string, RESULT> deserializer,
            Action<HttpWebRequest> headerHandler = null)
        {
            uri.Put(body, handler, errorHandler, serializer, deserializer, headerHandler.AppendBasicAuthentication(userName, password));
        }
        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>. The request body is expected to be formatted in XML.
        /// </summary>
        /// <typeparam name="BODY">A type of object to be sent to the server.</typeparam>
        /// <typeparam name="RESULT">The type of the result parameter.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="body">The body part of the request.</param>
        /// <param name="handler">The handler receiving the resultant object.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void PutXml<BODY, RESULT>(this Uri uri, string userName, string password,
            BODY body, Action<RESULT> handler, Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            uri.PutXml(body, handler, errorHandler, headerHandler.AppendXmlAndBasicAuthentication(userName, password));
        }
        /// <summary>
        /// Executes the "PUT" verb against the resource located at <paramref name="uri"/>. The request body is expected to be formatted in JSON.
        /// </summary>
        /// <typeparam name="BODY">A type of object to be sent to the server.</typeparam>
        /// <typeparam name="RESULT">The type of the result parameter.</typeparam>
        /// <param name="uri">The resource to be accessed.</param>
        /// <param name="userName">The user name part of the credentials.</param>
        /// <param name="password">The password part of the credentials.</param>
        /// <param name="body">The body part of the request.</param>
        /// <param name="handler">The handler receiving the resultant object.</param>
        /// <param name="errorHandler">The error handler.</param>
        /// <param name="headerHandler">Custom header handler.</param>
        public static void PutJson<BODY, RESULT>(this Uri uri, string userName, string password,
            BODY body, Action<RESULT> handler, Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            uri.PutJson<BODY, RESULT>(body, handler, errorHandler, headerHandler.AppendJsonAndBasicAuthentication(userName, password));
        }
    }
}
